Repository navigation
[Attention] Enable FA4 sparse MQA decode on Blackwell - #55866
Conversation
65d3925 to
c811040
Compare
|
This pull request has merge conflicts that must be resolved before it can be |
c811040 to
8925a7b
Compare
4204d78 to
a0ba252
Compare
|
This pull request has merge conflicts that must be resolved before it can be |
|
❌ This PR is 57 commits behind upstream |
|
/ci run |
|
✅ Triggered Buildkite CI #94216 for commit |
CI selector (shadow): 194 test steps (270 jobs) instead of 195 (271 jobs)Shadow mode: this changes nothing about what CI runs. It shows what the evidence-based selector would pick for this PR, next to today's rules. How it works. Feedback welcome: reply here if it would skip a step this change needs, or runs something unrelated.
Today's rules run everything for this diff. Selector would run (194)
Would skip (today's rules run them) (1)
Would add (today's rules do not run them) (0)none AMD mirrors: would skip (3)
AMD mirrors: would add (0)none 14 changed files · base |
|
This pull request has merge conflicts that must be resolved before it can be |
|
/ci run |
|
✅ CI is already running for this commit: https://buildkite.com/vllm/ci/builds/94216 |
Signed-off-by: Simon Veitner <sveitner@redhat.com>
Restore main's `flashattn_sparse_module` alias for vllm.v1.attention.backends.mla.flashattn_mla_sparse, imported under the `if current_platform.is_cuda():` guard, which was dropped during the merge resolution. Use it in `_record_fa4_kernels` and `test_fa4_sparse_gate` instead of their per-test imports. No behaviour change. Co-authored-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Veitner <sveitner@redhat.com>
|
/ci run |
|
❌ This PR is 30 commits behind upstream |
Signed-off-by: Simon Veitner <sveitner@redhat.com>
|
/ci run |
|
❌ This PR is 1 commit behind upstream |
Signed-off-by: Simon Veitner <sveitner@redhat.com>
|
/ci run |
|
✅ Triggered Buildkite CI #94434 for commit |
…taging Resolve against vllm-project#55866, which moved the HiSparse lane split into SparseMLACommonImpl.forward_mqa: the shared lane now stages prefills per group via staged_prefills and writes every lane into one output through an out= argument on _forward_mqa_kernel. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Matthew Bonanni <mbonanni@redhat.com>
…5866) Signed-off-by: Simon Veitner <sveitner@redhat.com> Co-authored-by: Lucas Wilkinson <lwilkins@redhat.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Lucas Wilkinson <LucasWilkinson@users.noreply.github.com> Co-authored-by: Matthew Bonanni <mbonanni@redhat.com> Signed-off-by: Andreas Karatzas <AndreasKaratzas@users.noreply.github.com>
[Attention] Enable FA4 sparse MQA decode on Blackwell
This adds
FLASH_ATTN_MLA_SPARSE_FA4, a sparse MLA backend for Blackwell with a BF16 KV cache. The FA4 CuTe DSL kernel from vllm-project/flash-attention#195 serves decode batches and the decode rows of mixed HiSparse batches. Every other batch runs on the trtllm-gen lane, as inFLASHINFER_MLA_SPARSE. At 16 or fewer query heads per rank the backend is the first choice, with and without HiSparse; above that head count it stays opt-in.The first commit, "Share sparse MLA MQA cache handling", will go up as its own PR and is only here until it lands. It moves index conversion and the HiSparse lane split from the FA3 and FlashInfer sparse MLA backends into
SparseMLACommonImpl.forward_mqa, so a backend implements only_forward_mqa_kernel(..., is_decode). The design is by @LucasWilkinson. One FA3 behaviour changes with it: FA3's plain path converts top-k through the index group's shared buffer, as FlashInfer already did, instead of once per layer. The values are identical while the layers of a group share block stride, block table and request ids, which index groups guarantee. A test pins leader and follower layers.The second commit is the FA4 backend on top of that hook:
flash_attn_varlen_funcforwardsgather_kv_indices,gather_kv_valid_lengthandq_vto FA4.FlashInferMLASparseImpl. Its hook runs the FA4 decode kernel whenis_decode, otherwise FlashInfer's trtllm-gen call with the LSE converted to base e.UNIFORM_BATCHCUDA graph support. Inheriting the builder brings the DCP workspace pre-size: an earlier version of this PR used the default 394 MiB trtllm workspace on its prefill lane and crashed under DCP 2 on a prefill step of about 8192 tokens, where the softmax-stats slab needs 513 MiB.index_topka multiple of 128, and a supported gathered head count under DCP.autotune_hisparse_decodecompiles the FA4 kernel before graph capture._uses_flat_kv_cache, since it reads the same flat KV cache as FlashInfer.The last commit bumps the flash-attention pin to vllm-project/flash-attention 2e3a6694, which has #195 and the sparse decode split-rule tuning for DCP shapes (vllm-project/flash-attention#200).
Performance
GLM-5.2 NVFP4-FP8 with BF16 KV on B300, TP4, FA4 against
FLASHINFER_MLA_SPARSEfrom the same tree (this PR onmaind71f662), change in median ITL (negative favours FA4). Plain and DCP 2 are averaged over two runs. The HiSparse column assumes #59309 is merged: it applies that PR's diff, pins the MoE autotune tactics so both backends run the same MoE kernels, and averages two server starts with two runs each.* One FA4 run measured 35.2 ms against 33.4 to 33.7 ms for the other three; without it the figure is +0.1%.
Under HiSparse FA4 is on par with FlashInfer, which did not justify a separate priority order. Per decode step, FA4's attention kernels take about 190 µs less than FlashInfer's at 4096 / 8, but start-to-start variance in all-reduce time is larger than that difference. On current
main, #59235 makes HiSparse about 0.45 ms per decode step slower for both backends, because it writesrequest_idsin every layer. #59309 moves those writes into the group leader's resolve, which brings the 57 follower layers' 171 kernels per step back out of the decode graph.Validation
pytest tests/v1/attention/test_sparse_mla_backends.py: 475 passed, 672 skipped.pytest tests/v1/e2e/general/test_hisparse.py: 5 passed (FlashInfer and FA4). The FlashInfer, KV cache layout, backend selection and masked-MHA routing tests pass as well.main, plain generations byte-identical.AI-assisted. The September 7 upstream search found no matching open FA4 sparse-MLA integration PR; related platform-specific work does not provide this SM100 backend.